home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr47
/
modex100.zip
/
UTILS.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-05-07
|
7KB
|
347 lines
;UTILS.ASM - Utilities for QuickBasic
PAGE 255, 132
.MODEL Medium
.286
; ==== MACROS ====
; Macro to OUT a 16 bit value to an I/O port
OUT_16 MACRO Register, Value
IFDIFI <Register>, <DX> ; If DX not setup
MOV DX, Register ; then Select Register
ENDIF
IFDIFI <Value>, <AX> ; If AX not setup
MOV AX, Value ; then Get Data Value
ENDIF
OUT DX, AX ; Set I/O Register(s)
ENDM
; Macro to OUT a 8 bit value to an I/O Port
OUT_8 MACRO Register, Value
IFDIFI <Register>, <DX> ; If DX not setup
MOV DX, Register ; then Select Register
ENDIF
IFDIFI <Value>, <AL> ; If AL not Setup
MOV AL, Value ; then Get Data Value
ENDIF
OUT DX, AL ; Set I/O Register
ENDM
; macros to PUSH and POP multiple registers
PUSHx MACRO R1, R2, R3, R4, R5, R6, R7, R8
IFNB <R1>
PUSH R1 ; Save R1
PUSHx R2, R3, R4, R5, R6, R7, R8
ENDIF
ENDM
POPx MACRO R1, R2, R3, R4, R5, R6, R7, R8
IFNB <R1>
POP R1 ; Restore R1
POPx R2, R3, R4, R5, R6, R7, R8
ENDIF
ENDM
; Macro to Clear a Register to 0
CLR MACRO Register
XOR Register, Register ; Set Register = 0
ENDM
; Macros to Decrement Counter & Jump on Condition
LOOPx MACRO Register, Destination
DEC Register ; Counter--
JNZ Destination ; Jump if not 0
ENDM
LOOPjz MACRO Register, Destination
DEC Register ; Counter--
JZ Destination ; Jump if 0
ENDM
; ==== General Constants ====
False EQU 0
True EQU -1
nil EQU 0
b EQU BYTE PTR
w EQU WORD PTR
d EQU DWORD PTR
o EQU OFFSET
f EQU FAR PTR
s EQU SHORT
?x4 EQU <?,?,?,?>
?x3 EQU <?,?,?>
IFDEF FARSTRINGS
EXTRN stringaddress:far
EXTRN stringlength:far
ENDIF
.Data
EVEN
RND_Seed DW 7397, 29447, 802
RND_Mult DW 179, 183, 182
RND_ModV DW 32771, 32779, 32783
CR_LF DB 13, 10 ; the CRLF data
.Code
;DOS_PRINT (Text$) - Print Text Directly to DOS console w/ CR/LF
PUBLIC DOS_PRINT
DP_Stack STRUC
DW ?x4 ; DI, SI, DS, BP
DD ? ; Caller
DP_Text DW ? ; Address of Text$ Descriptor
DP_Stack ENDS
DOS_PRINT PROC FAR
PUSHx BP, DS, SI, DI ; Preserve Important Registers
MOV BP, SP ; Set up Stack Frame
MOV SI, [BP].DP_Text ; Get Addr of Text$ descriptor
IFDEF FARSTRINGS
PUSH SI ; Push Addr of BC7 Decriptor Ptr
CALL stringaddress ; Get Address + Len of string!!!
; DX:AX = Addr CX = Len
MOV DS, DX ; DS = DX = Segment of string
MOV DX, AX ; DX = AX = Offset of String
ELSE
MOV CX, [SI] ; put its length into CX
MOV DX, [SI+02] ; now DS:DX points to the String
ENDIF
JCXZ @No_Print ; Don't Print if empty
MOV BX, 1 ; 1= DOS Handle for Display
MOV AH, 40h ; Write Text Function
INT 21h ; Call DOS to do it
@No_Print:
MOV AX, SEG DGROUP ; Restore DGroup
MOV DS, AX
MOV DX, o CR_LF ; Get Addr of CR/LF pair
MOV CX, 2 ; 2 Characters to Write
MOV BX, 1 ; 1= DOS Handle for Display
MOV AH, 40h ; Write Text Function
INT 21h ; Call DOS to do it
CLD ; Reset Direction Flag
POPx DI, SI, DS, BP ; Restore Saved Registers
RET 2 ; Exit & Clean Up Stack
DOS_PRINT ENDP
;DOS_PRINTS (Text$) - Print Text Directly to DOS console
PUBLIC DOS_PRINTS
DOS_PRINTS PROC FAR
PUSHx BP, DS, SI, DI ; Preserve Important Registers
MOV BP, SP ; Set up Stack Frame
MOV SI, [BP].DP_Text ; Get Addr of Text$ descriptor
IFDEF FARSTRINGS
PUSH SI ; Push Addr of BC7 Decriptor Ptr
CALL stringaddress ; Get Address + Len of string!!!
; DX:AX = Addr CX = Len
MOV DS, DX ; DS = DX = Segment of string
MOV DX, AX ; DX = AX = Offset of String
ELSE
MOV CX, [SI] ; put its length into CX
MOV DX, [SI+02] ; now DS:DX points to the String
ENDIF
JCXZ @DPS_Exit ; Don't Print if empty
MOV BX, 1 ; 1= DOS Handle for Display
MOV AH, 40h ; Write Text Function
INT 21h ; Call DOS to do it
@DPS_Exit:
CLD ; Reset Direction Flag
POPx DI, SI, DS, BP ; Restore Saved Registers
RET 2 ; Exit & Clean Up Stack
DOS_PRINTS ENDP
;======================
;SET_VIDEO_MODE (Mode%)
;======================
;
;Sets the Video Mode through the BIOS
;
PUBLIC SET_VIDEO_MODE
SVM_Stack STRUC
DW ?x4 ; DI, SI, DS, BP
DD ? ; Caller
SVM_Mode DB ?,? ; Desired Video Mode
SVM_Stack ENDS
SET_VIDEO_MODE PROC FAR
PUSHx BP, DS, SI, DI ; Preserve Important Registers
MOV BP, SP ; Set up Stack Frame
CLR AH ; Function 0
MOV AL, [BP].SVM_Mode ; Get Mode #
INT 10H ; Change Video Modes
@SVM_Exit:
POPx DI, SI, DS, BP ; Restore Saved Registers
RET 2 ; Exit & Clean Up Stack
SET_VIDEO_MODE ENDP
;==============
;SCAN_KEYBOARD%
;==============
;
;Function to scan keyboard for a pressed key
;
PUBLIC SCAN_KEYBOARD
SCAN_KEYBOARD PROC FAR
PUSHx BP, DS, SI, DI ; Preserve Important Registers
MOV AH, 01H ; Function #1
INT 16H ; Call Keyboard Driver
JZ @SK_NO_KEY ; Exit if Zero flag set
MOV AH, 00H ; Remove Key from Buffer
INT 16H ; Get Keycode in AX
OR AL, AL ; Low Byte Set (Ascii?)
JZ @SK_Exit ; if not, it's a F-Key
CLR AH ; Clear ScanCode if Ascii
JMP s @SK_Exit ; Return Key in AX
@SK_NO_KEY:
CLR AX ; Return Nil (no Keypress)
@SK_Exit:
CLD ; Reset Direction Flag
POPx DI, SI, DS, BP ; Restore Saved Registers
RET ; Exit & Clean Up Stack
SCAN_KEYBOARD ENDP
;====================
;RANDOM_INT (MaxInt%)
;====================
PUBLIC RANDOM_INT
RI_Stack STRUC
DW ? ; BP
DD ? ; Caller
RI_MaxVal DW ? ; Maximum Value to Return + 1
RI_Stack ENDS
RANDOM_INT PROC FAR
PUSH BP ; Preserve Important Registers
MOV BP, SP ; Set up Stack Frame
CLR BX ; BX is the data index
CLR CX ; CX is the accumulator
REPT 3
MOV AX, RND_Seed[BX] ; load the initial seed
MUL RND_Mult[BX] ; multiply it
DIV RND_ModV[BX] ; and obtain the Mod value
MOV RND_Seed[BX], DX ; save that for the next time
ADD CX, DX ; add it into the accumulator
INC BX
INC BX ; point to the next set of values
ENDM
MOV AX, CX ; AX = Random #
CLR DX ; DX = 0
DIV [BP].RI_MaxVal ; DX = DX:AX / MAxVal Remainder
MOV AX, DX
POP BP ; Restore BP
RET 2 ; back to BASIC with AX holding the result
RANDOM_INT ENDP
;===========
;INIT_RANDOM
;===========
PUBLIC INIT_RANDOM
INIT_RANDOM PROC FAR
CLR AX ; Segment = 0000
MOV ES, AX
MOV AX, ES:[046Ch] ; Get Timer Lo Word
XOR RND_Seed, AX ; Scramble 1st Seed
RET ; Exit & Clean Up Stack
INIT_RANDOM ENDP
;===========
;TIMER_COUNT
;===========
PUBLIC TIMER_COUNT
TIMER_COUNT PROC FAR
CLR AX ; Segment = 0000
MOV ES, AX
MOV AX, ES:[046Ch] ; Get Timer Lo Word
MOV DX, ES:[046Eh] ; Get Timer Hi Word
RET ; Exit & Clean Up Stack
TIMER_COUNT ENDP
END